package logic;

import gui.AboutScreen;
import gui.Board;
import gui.ClientServerSelectScreen;
import gui.HighscoresScreen;
import gui.LoadGameScreen;
import gui.MainMenuCanvas;
import gui.MenuOptions;
import gui.ServerConnectingToClientWaitingScreen;
import gui.StartingScreen;
import javax.microedition.lcdui.Alert;
import javax.microedition.lcdui.AlertType;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;

/**
 * MainMidlet class extends MIDlet class, represents game activity
 * @author Rekin
 *
 */
public class MainMidlet extends MIDlet {

	private MainMenuCanvas mainMenu;
	private MenuOptions menuOptions;
	private ClientServerSelectScreen clientServerSelectScreen;
	private Board board;
	private Engine engine;
	private static TempUserSettings settings;
	private BluetoothCommunicationHandler btch;
	private static MainMidlet midletInstance;
	public StatisticsManager stats;

	/**
	 * default constructor
	 */
	public MainMidlet() {
		midletInstance = this;
		stats = new StatisticsManager();
		mainMenu = new MainMenuCanvas();
		settings = new TempUserSettings();
	}
	
	/**
	 * @return setting of game
	 */
	public static TempUserSettings getTempSettings(){
		return settings;
	}

	/* (non-Javadoc)
	 * @see javax.microedition.midlet.MIDlet#destroyApp(boolean)
	 */
	protected void destroyApp(boolean arg0) throws MIDletStateChangeException {
		stats.saveDataToStatsFile();
	}

	/* (non-Javadoc)
	 * @see javax.microedition.midlet.MIDlet#pauseApp()
	 */
	protected void pauseApp() {
	}

	/* (non-Javadoc)
	 * @see javax.microedition.midlet.MIDlet#startApp()
	 */
	protected void startApp() throws MIDletStateChangeException {
		setDisplay(new StartingScreen());
	}
	
	/**
	 * actions when we shut down application
	 */
	public void shutDownApp(){
		try{
			if(btch != null){
				btch.closeConnections(); //when shutting down application, close bt connection if exists
			}
			destroyApp(false);
		}
		catch(MIDletStateChangeException ex){
			System.err.println("Midlet state change exception.");
		}
        notifyDestroyed();
    }
	
	/**
	 * start game event
	 */
	public void startGame(){
		switch(settings.getGameType()){
		case LogicHelper.gameTypeSinglePlayer:
			engine = new EngineSinglePlayer(settings);
			board = new Board(engine);
	        setDisplay(board);
			break;
		case LogicHelper.gameTypeMultiPlayerLocal:
			clientServerSelectScreen = new ClientServerSelectScreen("");
			setDisplay(clientServerSelectScreen);
			break;
		case LogicHelper.gameTypeMultiPlayerRemote:
			//in some future internet connect to server options form
			break;
		default:
			break;
		}
    }
	
	/**
	 * shows main menu screen
	 */
	public void showMainMenu(){
		setDisplay(mainMenu);
	}
	
	/**
	 * shows board screen after resume
	 */
	public void showResumeBoard(){
		setDisplay(board);
	}
	
	/**
	 * shows selection for bluetooth screen
	 */
	public void showSelectonForBluetooth(){
		setDisplay(clientServerSelectScreen);
	}
	
	/**
	 * shows options form screen
	 */
	public void showOptions(){
		if(menuOptions==null)
			menuOptions = new MenuOptions(settings);
		setDisplay(menuOptions);
	}
	
	/**
	 * shows client server selection screen
	 */
	public void showClientServerSelectScreen(){
		setDisplay(clientServerSelectScreen);
	}
	
	/**
	 * starts multiplayer game
	 */
	public void startMultiplayerBluetoothGame(){
		engine = new EngineBluetoothGame(btch, settings);
		if(!btch.isServer()){ //if client game
			//now wait for bluetooth to receive all information from SERVER before starting game
			setDisplay(new ServerConnectingToClientWaitingScreen());
		}
		//if it is server it is already in waiting screen - it will start when client name is received
	}
	
	/**
	 * this method is called by bluetooth receiver when all starting data has been received
	 */
	public void showMultiplayerGame(){
		//start game only if multiplayer engine is constructed
		if(engine instanceof EngineBluetoothGame){
			board = new Board(engine);
			board.doMultiplayerRevalidate();
	        setDisplay(board);
		}
	}
	
	/**
	 * shows about screen
	 */
	public void about(){
		setDisplay(new AboutScreen());
	}
	
	/**
	 * shows statistics screen
	 */
	public void highscores(){
		setDisplay(new HighscoresScreen());
	}
	
	/**
	 * shows load screen
	 */
	public void loadGame(){
		setDisplay(new LoadGameScreen());
	}
	
	/**
	 * action for load game
	 */
	public void prepareAndShowLoadedGame(){
		DataSaverLoader loader = new DataSaverLoader();
		if(loader.prepareSettings(settings)){
			engine = new EngineSinglePlayer(settings);
			if(loader.loadGameState(engine)){
				((EngineSinglePlayer)engine).checkBankrupcyCondition();
				board = new Board(engine);
				setDisplay(board);
			}
		}
		else{
			showMainMenu();
			Alert pop = LogicHelper.makePopup("Error",
    				"Unable to load game.", 3000, AlertType.ERROR);
    		MainMidlet.getMidletInstance().setDisplay(pop);
		}
	}
	
	/**
	 * @param h handler BluetoothCommunicationHandler
	 */
	public void setBluetoothCommunicationHandler(BluetoothCommunicationHandler h){
		btch=h;
	}
	
	/**
	 * @param screenToShow set this screen as current displayable
	 */
	public void setDisplay(Displayable screenToShow){
		Display.getDisplay(this).setCurrent(screenToShow);
	}
	
	/**
	 * @return MIDlet instance
	 */
	public static MainMidlet getMidletInstance() {
		return midletInstance;
	}

	/**
	 * @return board on which game is run
	 */
	public Board getBoard() {
		return board;
	}
}
